package fhq.hcmute.edu.vn.event;

import java.awt.event.KeyEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;

import org.apache.commons.io.IOUtils;

import fhq.hcmute.edu.vn.config.AppConfig;
import fhq.hcmute.edu.vn.gui.PictureFrame;
import fhq.hcmute.edu.vn.keyboard.KeyCode;
import fhq.hcmute.edu.vn.system.MyFile;
import fhq.hcmute.edu.vn.system.MyFolder;
import fhq.hcmute.edu.vn.system.util.DiskManager;
import fhq.hcmute.edu.vn.system.util.MyProgram;

public final class Command {
	private static KeyboardEvent keyboardEvent;
	private static MouseEvent mouseEvent;
	private static HashMap<Integer, String> mapImage;

	private Command() {

	}

	static {
		keyboardEvent = new KeyboardEvent();
		mouseEvent = new MouseEvent();
		mapImage = new HashMap<>();
	}

	public static void mouseMove(Object[] data) {
		float x = (float) data[0];
		float y = (float) data[1];
		mouseEvent.mouseMove(x, y);
	}
	public static void mouseDrop() {
		mouseEvent.leftClick();
	}
	public static void mouseDrap() {
		mouseEvent.leftRelease();
	}
	public static void mouseLeftClick() {
		mouseEvent.leftClick();
		mouseEvent.leftRelease();
	}

	public static void preziNextSlide() {
		int vk_KeyRight = KeyEvent.VK_RIGHT;
		keyboardEvent.press(vk_KeyRight);
	}

	public static void preziPreviousSlide() {
		int vk_KeyLeft = KeyEvent.VK_LEFT;
		keyboardEvent.press(vk_KeyLeft);
	}

	public static void preziZoomIn() {
		mouseEvent.mouseScrollUp(1);
	}

	public static void preziZoomOut() {
		mouseEvent.mouseScrollDown(1);
	}

	public static void preziEnterFullScreen() {
		int vk_keyCtrl = KeyEvent.VK_CONTROL;
		int vk_keyF = KeyEvent.VK_F;
		keyboardEvent.multiPress(vk_keyCtrl, vk_keyF);
	}

	public static void preziExitFullScreen() {
		int vk_KeyLeft = KeyEvent.VK_ESCAPE;
		keyboardEvent.press(vk_KeyLeft);
	}

	public static void preziBlackout() {
		int vk_KeyLeft = KeyEvent.VK_B;
		keyboardEvent.press(vk_KeyLeft);
	}

	public static void mouseRightClick() {
		mouseEvent.rightClick();
		mouseEvent.rightRelease();
	}

	public static void mouseDoubleClick() {
		mouseLeftClick();
		mouseLeftClick();
	}

	public static void mouseScrollUp(Object[] data) {
		mouseEvent.mouseScrollUp((int) data[0]);
	}

	public static void mouseScrollDown(Object[] data) {
		mouseEvent.mouseScrollDown((int) data[0]);
	}

	public static void zoomIn() {
		int vk_keyWin = KeyEvent.VK_WINDOWS;
		int vk_keyPlus = KeyEvent.VK_EQUALS;
		MyProgram myProgram = new MyProgram();
		myProgram.run("magnify.exe");
		keyboardEvent.multiPress(vk_keyWin, vk_keyPlus);
	}

	public static void zoomOut() {
		int vk_keyWin = KeyEvent.VK_WINDOWS;
		int vk_keySub = KeyEvent.VK_SUBTRACT;
		MyProgram myProgram = new MyProgram();
		myProgram.run("magnify.exe");
		keyboardEvent.multiPress(vk_keyWin, vk_keySub);
	}

	public static void keyboardPress(Object[] data) {
		int value = (int) data[0];
		keyboardEvent.press(value);
	}

	public static void keyboardPress(KeyCode keyCode) {
		keyboardEvent.press(keyCode);
	}

	public static void keyboardRightArrow(Object[] data) {
		int value = (int) data[0];
		keyboardEvent.pressLeft(value);
	}

	public static void keyboardRightArrow(int value) {
		keyboardEvent.pressLeft(value);
	}

	public static void keyboardLeftArrow(Object[] data) {
		int value = (int) data[0];
		keyboardEvent.pressRight(value);
	}

	public static MyFolder changeDirectory(Object[] data) {
		MyFolder value = (MyFolder) data[0];
		if (DiskManager.changeDirectory(value.getName())) {
			return DiskManager.list();
		}
		return null;
	}

	public static MyFolder upToRoot() {
		DiskManager.upToRoot();
		return DiskManager.list();
	}

	public static boolean Excute(Object[] data) {
		MyFile file = (MyFile) data[0];
		MyProgram program = new MyProgram();
		return program.run(file.getPath() + "\\" + file.getName());
	}

	public static MyFolder refresh() {
		return DiskManager.list();
	}

	public static MyFolder turnBack() {
		if (DiskManager.changeDirectory())
			return DiskManager.list();
		return null;
	}

	public static MyFolder search(Object[] datas) {
		MyFolder in = null;
		String fileName = null;
		String[] fileType = null;
		for (Object obj : datas) {
			if (obj instanceof MyFolder) {
				in = (MyFolder) obj;
			} else if (obj instanceof String) {
				fileName = (String) obj;
			} else if (obj instanceof String[]) {
				fileType = (String[]) obj;
			}
		}
		if (in == null) {
			in = pwd();
		}
		return DiskManager.search(in, fileName, fileType);
	}

	public static MyFolder pwd() {
		return DiskManager.pwd();
	}

	public static boolean reviewImage(Object[] datas) {
		int imageID = (int) datas[0];
		String path = mapImage.get(imageID);
		File file = new File(path);
		try {
			FileInputStream fileInputStream = new FileInputStream(file);
			byte[] byteData = IOUtils.toByteArray(fileInputStream);
			PictureFrame.getInstance().setImage(byteData);
			return true;
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return false;
	}

	public static boolean removeImage(Object[] datas) {
		if (AppConfig.getInstance().getPictureFrameSetting().isSavePicture()) {
			for (int i = 0; i < mapImage.size(); i++) {
				int imageID = (int) datas[0];
				String path = mapImage.get(imageID);
				File file = new File(path);
				if (file.exists()) {
					file.delete();
					return true;
				}
			}
		}
		return false;
	}

	public static boolean removeAllImages() {
		if (AppConfig.getInstance().getPictureFrameSetting().isSavePicture()) {
			for (int i = 0; i < mapImage.size(); i++) {
				String path = mapImage.get(i);
				File file = new File(path);
				if (file.exists()) {
					file.delete();
				}
			}
		}
		return true;
	}

	public static boolean postImage(Object[] datas) {
		int imageID = (int) datas[0];
		byte[] arr = (byte[]) datas[1];
		try {
			PictureFrame frame = PictureFrame.getInstance();
			frame.setImage(arr);
			frame.showFrame();
			if (AppConfig.getInstance().getPictureFrameSetting()
					.isSavePicture()) {
				writeImageToFile(arr, imageID);
			}
			return true;
		} catch (Exception e) {

		}
		return false;
	}

	private static void writeImageToFile(byte[] arr, int imageID) {
		try {
			File folder = new File("Images");
			if (!folder.exists()) {
				folder.mkdir();
			}
			String path = "Images/img_" + System.currentTimeMillis() + ".jpg";
			File file = new File(path);
			FileOutputStream outputStream = new FileOutputStream(file);
			outputStream.write(arr);
			outputStream.close();
			mapImage.put(imageID, path);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
